<template>
    <div class="s-canvas">
        <canvas :style=style id="s-canvas"/>
    </div>
</template>
<script lang="ts">
    import {Component, Prop, Vue, Watch} from 'vue-property-decorator'

    @Component({
        name: 'MiCaptcha'
    })
    export default class MiCaptcha extends Vue {
        //默认注册码
        @Prop({default: 1234}) private identifyCode!: any;
        //字体最小值
        @Prop({default: 80}) private fontSizeMin!: any;
        //字体最大值
        @Prop({default: 80}) private fontSizeMax!: any;
        //验证码图片背景色最小值
        @Prop({default: 300}) private backgroundColorMin!: any;
        // 验证码图片背景色最大值
        @Prop({default: 300}) private backgroundColorMax!: any;
        // 背景干扰点最小值
        @Prop({default: 40}) private dotColorMin!: any;
        // 背景干扰点最大值
        @Prop({default: 40}) private dotColorMax!: any;
        // 容器宽度
        @Prop({default: 300}) private width!: any;
        // 容器高度
        @Prop({default: 170}) private height!: any;

        style = {width: 100 + '%', height: 100 + '%'};

        // 生成一个随机数
        randomNum(min: any, max: any) {
            return Math.floor(Math.random() * (max - min) + min)
        }

        // 生成一个随机的颜色
        randomColor(min: any, max: any) {
            let r = this.randomNum(min, max);
            let g = this.randomNum(min, max);
            let b = this.randomNum(min, max);
            return 'rgb(' + r + ',' + g + ',' + b + ')'
        }

        //绘制内容
        drawPic() {
            let canvas: any = document.getElementById('s-canvas');
            let ctx = canvas.getContext('2d');
            ctx.textBaseline = 'bottom';
            // 绘制背景
            ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax);
            ctx.fillRect(0, 0, this.width, this.height);
            // 绘制文字
            for (let i = 0; i < this.identifyCode.length; i++) {
                this.drawText(ctx, this.identifyCode[i], i)
            }
            this.drawLine(ctx);
            this.drawDot(ctx);
        }

        drawText(ctx: any, txt: any, i: any) {
            // 随机生成字体颜色
            ctx.fillStyle = this.randomColor(50, 249);
            // 随机生成字体大小
            ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei';
            let x = (i + 1) * (this.width / (this.identifyCode.length + 1));
            let y = this.randomNum(this.fontSizeMax, this.height - 5);
            let deg = this.randomNum(-30, 30);
            // 修改坐标原点和旋转角度
            ctx.translate(x, y);
            ctx.rotate(deg * Math.PI / 180);
            ctx.fillText(txt, 0, 0);
            // 恢复坐标原点和旋转角度
            ctx.rotate(-deg * Math.PI / 180);
            ctx.translate(-x, -y);
        }

        drawLine(ctx: any) {
            // 绘制干扰线
            for (let i = 0; i < 4; i++) {
                ctx.strokeStyle = this.randomColor(100, 200);
                ctx.beginPath();
                ctx.moveTo(this.randomNum(0, this.width), this.randomNum(0, this.height));
                ctx.lineTo(this.randomNum(0, this.width), this.randomNum(0, this.height));
                ctx.stroke();
            }
        }

        drawDot(ctx: any) {
            // 绘制干扰点
            for (let i = 0; i < 30; i++) {
                ctx.fillStyle = this.randomColor(0, 255);
                ctx.beginPath();
                ctx.arc(this.randomNum(0, this.width), this.randomNum(0, this.height), 1, 0, 2 * Math.PI);
                ctx.fill();
            }
        }

        //监听识别码
        @Watch('identifyCode')
        identifyCodeWatch() {
            this.drawPic();
        }

        mounted() {
            this.drawPic()
        }

    }
</script>
<style scoped>

</style>
